#if !defined(_COMMANDDESCRIPTOR_H)
#define _COMMANDDESCRIPTOR_H

#include <boost/foreach.hpp>

#include "alias.h"
#include "InputParameter.h"
#include "OutputParameter.h"
#include "SStructTypeDescriptor.h"

CREATE_ALIAS( CommandDescriptor )
CREATE_MAP_ALIAS( CommandDescriptor )

/**
 * Class use to store the definition of a plugin command.
 */
class DECLARATION_DLL CommandDescriptor 
{
	/** The plugin name that define the command. */
	string pluginName;

	/** The name of the command. */
	string name;

	/** The description of the command. */
	string description;

	/** Vector use to store information about command input parameters. */
	InputParameterSpVectorSp inputParameters;

	/** Vector use to store information about command output parameters. */
	OutputParameterSpVectorSp outputParameters;

	/**
	 * Create a CommandDescriptor object.
	 */
	CommandDescriptor(string pluginName, string name, string description);

public:

	/**
	 * Get the name of the command (is not fully qualified).
	 */
	virtual string GetName()
	{
		return name;
	}

	/**
	* Get the name of the plugin that define this command.
	*/
	virtual string GetPluginName()
	{
		return pluginName;
	}

	/**
	 * Get the fully qualified name of the command.
	 **/
	virtual string GetFullyQualifiedName()
	{
		return Utility::GetFullyQualifiedName(pluginName, name);
	}

	/**
	* Get the description of the command.
	**/
	virtual string GetDescription()
	{
		return description;
	}

	/**
	 * Add an input parameter of simple type.
	 */
	virtual void AddInputParameter(string name, string description, SType type)
	{
		inputParameters->push_back( InputParameter::Create( name, description, type) );		
	}

	/**
	 * Add an input parameter of complex type.
	 */
    virtual void AddInputParameter(string name, string description, TypeDescriptorSp typeDescriptor)
	{
		inputParameters->push_back( InputParameter::Create( name, description, typeDescriptor) );		
	}

	/**
	 * Add an output parameter of simple type.
	 */
	virtual void AddOutputParameter(string name, string description, SType type)
	{
		outputParameters->push_back( OutputParameter::Create( name, description, type) );		
	}

	/**
	 * Add an output parameter of complex type.
	 */
    virtual void AddOutputParameter(string name, string description, TypeDescriptorSp typeDescriptor)
	{
		outputParameters->push_back( OutputParameter::Create( name, description, typeDescriptor) );		
	}

	/**
	 * Get the number of input parameters.
	 */
	virtual int GetNumberOfInputParameters()
	{
		return inputParameters->size();
	}

	/**
	 * Get the number of output parameters.
	 */
	virtual int GetNumberOfOutputParameters()
	{
		return outputParameters->size();
	}

	/**
	 * Get info about an input parameter in the index position.
	 */
	virtual InputParameterSp GetInputParameter(int index);
	
	/**
	 * Get info about an input parameter with a specific name.
	 */
	virtual InputParameterSp GetInputParameter(string name);

	/**
	 * Returns true if an input parameter with a specific name is defined.
	 */
	virtual bool IsInputParameterDefined(string name);

	/**
	 * Get info about an output parameter in the index position.
	 */
	virtual OutputParameterSp GetOutputParameter(int index);

	/**
	 * Get info about an output parameter with a specific name.
	 */
	virtual OutputParameterSp GetOutputParameter(string name);

	/**
	 * Create the struct type descriptor that define inputs parameters.
	 */
	virtual SStructTypeDescriptorSp GetInputsTypeDescriptor();

	/**
	 * Create the struct type descriptor that define outputs parameters.
	 */
	virtual SStructTypeDescriptorSp GetOutputsTypeDescriptor();

	/**
	 * Returns true is an output parameter with a specific name is defined.
	 */
	virtual bool IsOutputParameterDefined(string name);

	/**
	 * Factory method to create a CommandDescriptor.
	 */
	static CommandDescriptorSp Create(string pluginName, string name, string description);

};

#endif  //_COMMANDDESCRIPTOR_H
